//
//  RunningWidget.m
//  精通Objective-C
//
//  Created by 花强 on 2017/12/18.
//  Copyright © 2017年 花强. All rights reserved.
//

#import "C9RunningWidget.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation C9RunningWidget

//用于显示选择器的方法实现函数
static void display(id self,SEL _cmd){
    NSLog(@"Invoking method with selector %@ on %@ instance",NSStringFromSelector(_cmd),NSStringFromClass([self class]));
}

-(void)test9_2{
    //创建一个类对
    Class widgetClass = objc_allocateClassPair([NSObject class], "C9Widget", 0);
    
    //向这个类添加一个方法
    const char * types = "v@:";
    class_addMethod(widgetClass, @selector(display), (IMP)display, types);
    
    //向类添加一个实例变量
    const char * height = "height";
    class_addIvar(widgetClass, height, sizeof(id), rint(log2(sizeof(id))), @encode(id));
    
    //注册这个类
    objc_registerClassPair(widgetClass);
    
    //创建一个widget实例并设置实例变量的值
    id widget = [[widgetClass alloc] init];
    id value = [NSNumber numberWithInteger:15];
    [widget setValue:value forKey:[NSString stringWithUTF8String:height]];
    NSLog(@"W height = %@",[widget valueForKey:[NSString stringWithUTF8String:height]]);
    
    //向widget实例发送一个消息
    objc_msgSend(widget, NSSelectorFromString(@"display"));
    //Build Setting--> Apple LLVM 6.0 - Preprocessing--> Enable Strict Checking of objc_msgSend Calls  改为 NO
    
    //以动态方式向widget实例添加一个变量（关联对象）
    NSNumber * width = [NSNumber numberWithInteger:10];
    objc_setAssociatedObject(widget, @"width", width, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    //获取该变量的值并显示它
    id result = objc_getAssociatedObject(widget, @"width");
    NSLog(@"W width = %@",result);
    
}

@end
